import json
import random
import time
from collections import defaultdict
from datetime import datetime

import gevent
import requests
import yaml
from faker import Faker
from gevent.pool import Pool
class AtomicCounter:
    def __init__(self):
        self.value = 0
        self._lock = gevent.lock.Semaphore()
    def increment(self):
        with  self._lock:
            self.value += 1


with open("D:\SaasFoodLimit\config.yml", "r", encoding="utf-8") as f:
    config = yaml.load(f, Loader=yaml.FullLoader)
success_counter = AtomicCounter()
fail_counter = AtomicCounter()
error_records = defaultdict(AtomicCounter)
def order_request(member_id):
    header = config["header"]
    url = "https://testsaasapi.keyijievip.com/order/api/stall-code/order/submit"
    order_id = "0123456789"
    data = {
          "cartList": [
            {
              "stallId": 1807951900709605378,
              "productId": 7585,
              "productSkuId": None,
              "productNumber": 1,
              "limitNumber": None,
              "mealFlag": 0,
              "productBundle": None,
              "remarks": None,
              "failure": False
            }
          ],
          "orderSource": None,
          "memberId": member_id,
          "canteenId": 1807951831235153922,
          "canteenName": "田庆测试食堂",
          "mealId": 3356,
          "mealLicenseId": 3352,
          "mealName": "夜宵",
          "machineCreateDate": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
          "payableAmount": None,
          "discountAmount": None,
          "actualAmount": 0.01,
          "uniqueNo": "".join(random.choices(order_id,k=20)),
          "remarks": "",
          "paymentMode": "CARD_MEAL",
          "couponList": [],
          "isUseScore": False,
          "orderPid": None
        }
    try:
        resp = requests.post(
            url=url,
            headers=header,
            data=json.dumps(data),
            timeout=5
        )
        print(resp.json())
        resp.raise_for_status()
        if resp.json().get("code") != 0:
            log_failure("下单", resp.json().get("msg", "未知业务错误"))
            return
    except Exception as e:
        log_failure("下单", str(e))
        return
    success_counter.increment()
def log_failure(step, error):
    fail_counter.increment()
    error_records[step].increment()
    print(f"❌ 失败接口 {step}: {error}")
    # 最终统计输出

def print_statistics():
    print("\n📊 压力测试结果:")
    print(f"✅ 成功请求: {success_counter.value}")
    print(f"❌ 失败请求: {fail_counter.value}")
    print("🔧 错误分布:")
    for step, counter in error_records.items():
        print(f"  {step}: {counter.value}次失败")
if __name__ == '__main__':
    f = Faker("zh_CN")
    url_xin = "https://testsaasapi.keyijievip.com/member/member/saveMemberCardInfo"
    header = config["header"]

    for i in range(config["number"]):
        data_xin = {"memberName": f.name(), "memberCategoryId": "", "memberCategoryName": "",
                    "employeeNo": f.phone_number(), "password": "8888", "sex": "0", "faceImage": "",
                    "phone": f.phone_number(), "certificateNo": "", "cardNo": "", "cardTypeId": "10110",
                    "cardTypeLicenseId": "10110", "cardTypeName": "测试卡", "openCardAmount": 99999999,
                    "cardDeposit": 0, "cardCost": 0, "paymentModeId": "1801491038476877825",
                    "paymentModeName": "现金支付", "memberDeptId": "1802569625167716353", "memberDeptName": "SAAS部门",
                    "deptIds": ["1807951831235153922"], "overdraftAmount": 0, "expireDate": [], "expireStartDate": "",
                    "expireEndDate": "", "parentId": 0, "cardChipNo": "", "payCode": "", "payModeCode": "CASH",
                    "faceData": "", "deptId": "1807951831235153922", "userId": None}

        resp = requests.post(
            url=url_xin,
            headers=header,
            data=json.dumps(data_xin),
            timeout=5
        )
        time.sleep(0.5)
        print(resp.json())
    print("测试数据创建完成")
    time.sleep(0.1)
    # 初始化测试数据
    url = "https://testsaasapi.keyijievip.com/member/member/getMemberListPage"

    data = {"deptIds": ["1807951831235153922"], "expireDate": [], "memberCategoryIds": [], "cardTypeIds": [],
            "memberIds": [], "statusGroup": [0, 1], "expired": False, "memberDeptId": "1802569625167716353",
            "current": 1, "size": 10, "descs": "", "ascs": ""}
    # 查询用户数据
    response = requests.post(url, headers=header, data=json.dumps(data))
    print("测试数据查询完成")
    # 提取前5个会员ID
    member_ids_list = []
    if response.ok:
        try:
            response_data = response.json()
            records = response_data.get('data', {}).get('records', [])

            # 只取前5个记录
            for i, record in enumerate(records):
                if i >= config["number"]:  # 只处理前5条记录
                    break

                if 'memberId' in record:
                    member_ids_list.append(record['memberId'])
        except (ValueError, TypeError) as e:
            print(f"⚠️ JSON解析错误: {str(e)}")
    else:
        print(f"⚠️ API请求失败: HTTP {response.status_code} - {response.reason}")
    print(member_ids_list)

    pool = Pool(config["number"])
    jobs = [pool.spawn(order_request, member_id) for member_id in member_ids_list]
    gevent.joinall(jobs)
    print_statistics()
